package com.imooc.service.impl;

import com.imooc.enums.OrderStatusEnum;
import com.imooc.enums.YesOrNo;
import com.imooc.mapper.OrderItemsMapper;
import com.imooc.mapper.OrderStatusMapper;
import com.imooc.mapper.OrdersMapper;
import com.imooc.pojo.Items;
import com.imooc.pojo.ItemsSpec;
import com.imooc.pojo.OrderItems;
import com.imooc.pojo.OrderStatus;
import com.imooc.pojo.Orders;
import com.imooc.pojo.UserAddress;
import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.pojo.bo.SubmitOrderBO;
import com.imooc.pojo.vo.MerchantOrdersVO;
import com.imooc.pojo.vo.OrderVO;
import com.imooc.service.AddressService;
import com.imooc.service.ItemService;
import com.imooc.service.OrderService;
import com.imooc.utils.DateUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderServiceImpl implements OrderService {

  @Autowired
  private OrdersMapper ordersMapper;

  @Autowired
  private OrderItemsMapper orderItemsMapper;

  @Autowired
  private OrderStatusMapper orderStatusMapper;

  @Autowired
  private AddressService addressService;

  @Autowired
  private ItemService itemService;

  @Autowired
  private Sid sid;

  @Transactional(propagation = Propagation.REQUIRED)
  @Override
  public OrderVO createOrder(List<ShopcartBO> shopcartList, SubmitOrderBO submitOrderBO) {

    String userId = submitOrderBO.getUserId();
    String addressId = submitOrderBO.getAddressId();
    String itemSpecIds = submitOrderBO.getItemSpecIds();
    Integer payMethod = submitOrderBO.getPayMethod();
    String leftMsg = submitOrderBO.getLeftMsg();
    // 包邮费用设置为0
    Integer postAmount = 0;

    String orderId = sid.nextShort();

    UserAddress address = addressService.queryUserAddress(userId, addressId);

    // 1. 新订单数据保存
    Orders newOrder = new Orders();
    newOrder.setId(orderId);
    newOrder.setUserId(userId);

    newOrder.setReceiverName(address.getReceiver());
    newOrder.setReceiverMobile(address.getMobile());
    newOrder.setReceiverAddress(address.getProvince() + " "
        + address.getCity() + " "
        + address.getDistrict() + " "
        + address.getDetail());

//        newOrder.setTotalAmount();
//        newOrder.setRealPayAmount();
    newOrder.setPostAmount(postAmount);

    newOrder.setPayMethod(payMethod);
    newOrder.setLeftMsg(leftMsg);

    newOrder.setIsComment(YesOrNo.NO.type);
    newOrder.setIsDelete(YesOrNo.NO.type);
    newOrder.setCreatedTime(new Date());
    newOrder.setUpdatedTime(new Date());

    // 2. 循环根据itemSpecIds保存订单商品信息表
    String itemSpecIdArr[] = itemSpecIds.split(",");
    Integer totalAmount = 0;    // 商品原价累计
    Integer realPayAmount = 0;  // 优惠后的实际支付价格累计
    List<ShopcartBO> toBeRemovedShopcartList = new ArrayList<>();
    for (String itemSpecId : itemSpecIdArr) {

      ShopcartBO cartItem = getByCountsFromShopcart(shopcartList, itemSpecId);
      //  整合redis后，商品购买的数量重新从redis的购物车中获取
      int buyCounts = cartItem.getBuyCounts();
      toBeRemovedShopcartList.add(cartItem);

      // 2.1 根据规格id，查询规格的具体信息，主要获取价格
      ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);
      totalAmount += itemSpec.getPriceNormal() * buyCounts;
      realPayAmount += itemSpec.getPriceDiscount() * buyCounts;

      // 2.2 根据商品id，获得商品信息以及商品图片
      String itemId = itemSpec.getItemId();
      Items item = itemService.queryItemById(itemId);
      String imgUrl = itemService.queryItemMainImgById(itemId);

      // 2.3 循环保存子订单数据到数据库
      String subOrderId = sid.nextShort();
      OrderItems subOrderItem = new OrderItems();
      subOrderItem.setId(subOrderId);
      subOrderItem.setOrderId(orderId);
      subOrderItem.setItemId(itemId);
      subOrderItem.setItemName(item.getItemName());
      subOrderItem.setItemImg(imgUrl);
      subOrderItem.setBuyCounts(buyCounts);
      subOrderItem.setItemSpecId(itemSpecId);
      subOrderItem.setItemSpecName(itemSpec.getName());
      subOrderItem.setPrice(itemSpec.getPriceDiscount());
      orderItemsMapper.insert(subOrderItem);

      // 2.4 在用户提交订单以后，规格表中需要扣除库存
      itemService.decreaseItemSpecStock(itemSpecId, buyCounts);
    }

    newOrder.setTotalAmount(totalAmount);
    newOrder.setRealPayAmount(realPayAmount);
    ordersMapper.insert(newOrder);

    // 3. 保存订单状态表
    OrderStatus waitPayOrderStatus = new OrderStatus();
    waitPayOrderStatus.setOrderId(orderId);
    waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
    waitPayOrderStatus.setCreatedTime(new Date());
    orderStatusMapper.insert(waitPayOrderStatus);

    // 4. 构建商户订单，用于传给支付中心
    MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
    merchantOrdersVO.setMerchantOrderId(orderId);
    merchantOrdersVO.setMerchantUserId(userId);
    merchantOrdersVO.setAmount(realPayAmount + postAmount);
    merchantOrdersVO.setPayMethod(payMethod);

    // 5. 构建自定义订单vo
    OrderVO orderVO = new OrderVO();
    orderVO.setOrderId(orderId);
    orderVO.setMerchantOrdersVO(merchantOrdersVO);
    orderVO.setToBeRemovedShopcartList(toBeRemovedShopcartList);

    return orderVO;
  }

  /**
   * 从redis中的购物车里面获取商品，目的：counts
   * @param shopcartList
   * @param specId
   * @return
   */
  private ShopcartBO getByCountsFromShopcart(List<ShopcartBO> shopcartList, String specId) {
    for (ShopcartBO cart : shopcartList) {
      if (cart.getSpecId().equals(specId)) {
        return cart;
      }
    }
    return null;
  }

  @Transactional(propagation = Propagation.REQUIRED)
  @Override
  public void updateOrderStatus(String orderId, Integer orderStatus) {

    OrderStatus paidStatus = new OrderStatus();
    paidStatus.setOrderId(orderId);
    paidStatus.setOrderStatus(orderStatus);
    paidStatus.setPayTime(new Date());

    orderStatusMapper.updateByPrimaryKeySelective(paidStatus);
  }

  @Transactional(propagation = Propagation.SUPPORTS)
  @Override
  public OrderStatus queryOrderStatusInfo(String orderId) {
    return orderStatusMapper.selectByPrimaryKey(orderId);
  }

  @Transactional(propagation = Propagation.REQUIRED)
  @Override
  public void closeOrder() {

    // 查询所有未付款订单，判断时间是否超时（1天），超时则关闭交易
    OrderStatus queryOrder = new OrderStatus();
    queryOrder.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
    List<OrderStatus> list = orderStatusMapper.select(queryOrder);
    for (OrderStatus os : list) {
      // 获得订单创建时间
      Date createdTime = os.getCreatedTime();
      // 和当前时间进行对比
      int days = DateUtil.daysBetween(createdTime, new Date());
      if (days >= 1) {
        // 超过1天，关闭订单
        doCloseOrder(os.getOrderId());
      }
    }
  }

  @Transactional(propagation = Propagation.REQUIRED)
  void doCloseOrder(String orderId) {
    OrderStatus close = new OrderStatus();
    close.setOrderId(orderId);
    close.setOrderStatus(OrderStatusEnum.CLOSE.type);
    close.setCloseTime(new Date());
    orderStatusMapper.updateByPrimaryKeySelective(close);
  }
}
